﻿/// <reference path="jquery-1.8.2.js"/>
/// <reference path="jquery.functions.js"/>
/// <reference path="../Lang/widget-nl.js"/>

(function ($) {
	$.presence = function (options) {

		var settings = {
			'templateUrl': '',
			'serviceUrl': '',
			'refreshRate': 4000,
			'language': '',
			'languageBaseUrl': '',
			'statusImageBaseUrl': '', //a base url of a directory containing presense-sensitive pictures
			'statusImageExtension': '.jpg',
			'query': '',
			'sortby': '',
			'sortdirection': '',
			'sips': [],
			'groups': [],
		    'usePresenceTempInit': false,
			'onPresenceItemUpdated': function () {
			},
			'onGroupPresenceItemUpdated': function () {
			}
		};

		if (options) {
			$.extend(settings, options);
		}

		if (settings.serviceUrl == "") {
			$.error("jquery.ucma.presence requires a service URL.");
		}

		if (settings.languageBaseUrl == "") {
			$.error("jquery.ucma.presence requires a language base URL for localization.");
		}

		$(document).ready(function () {
			$(function () {

				var localizeSettings = { loadBase: true, timeout: 0 };

				if (settings.language != '') {
					localizeSettings.language = settings.language;
				} else {
					var languageQuerystring = $.getUrlVar("lang");

					if (languageQuerystring != null && languageQuerystring != '') {
						localizeSettings.language = languageQuerystring;
					}
				}

				$.localise(settings.languageBaseUrl, localizeSettings);
			});
		});


		if (settings.templateUrl != '') {
			$.get(settings.templateUrl, function (data) {

				var personTemplate = $(data).find("#PersonTemplate");
				if (personTemplate.length > 0) {
					$('#presenceitemTemplate').html(personTemplate.html());
				}

				var groupTemplate = $(data).find("#GroupTemplate");
				if (groupTemplate.length > 0) {
					$('#grouppresenceitemTemplate').html(groupTemplate.html());
				}

				initPresence(settings);

			});
		} else {
			initPresence(settings);
		}
	};


	// Initialize Presence

	function initPresence(settings) {

		// retrieve presences
		serviceGetPersonsAndGroups(settings);

		// show presences based on sips or groups already on the page
		//showPresences(settings);

	}

	// Get persons and groups from the service 

	function serviceGetPersonsAndGroups(settings) {

		//  get sips from settings
		var sipQuery = '';
		if (settings.sips != '') {
			$.each(settings.sips, function (index, sip) {
				sipQuery = sipQuery + sip.sip + ",";
			});
		}

		// get querystring
		var query = $.getQuerystring();

		if (query == '' && settings.query != '') {
			query = settings.query;
		}

		if (query != null && query != '') {
			query = encodeURIComponent(query);
		}

		// get groups from querystring
		var groupArray = new Array();
		var querystring = $.getUrlVar("grp");
		if (querystring != null) {
			var qsgroups = querystring.split('+');
			$.each(qsgroups, function (index, grp) {
				if ($.inArray(grp, groupArray) == -1) {
					groupArray.push(grp);
				}
			});
		}

		// get groups from settings
		if (settings.groups != '') {
			var setgroups = settings.groups.split(',');
			$.each(setgroups, function (index, grp) {
				if ($.inArray(grp, groupArray) == -1) {
					groupArray.push(grp);
				}
			});
		}

		var groupQuery = '';
		if (groupArray.length > 0) {
			groupQuery = groupArray.join(',');
		}

		if (sipQuery != '' || query != '' || groupQuery != '') {

			var serviceUrl = settings.serviceUrl + 'GetPersonsAndGroups?query=' + query + "&sips=" + sipQuery + '&groups=' + groupQuery + '&r=' + Math.random();

			$.ajax({
				type: 'GET',
				url: serviceUrl,
				dataType: 'jsonp',
				success: function (entries) {

					if (entries != null && entries.length > 0) {


					    for (var i = 0; i < entries.length; i++) {
					        // load person template
					        if (entries[i].person != null && $("#presenceitemTemplate").length > 0) {
					            $("#presenceitemTemplate").tmpl(entries[i].person).appendTo("#presenceitemContainer");
					        }

					        // load group template
					        if (entries[i].group != null && $("#grouppresenceitemTemplate").length > 0) {
					            $("#grouppresenceitemTemplate").tmpl(entries[i].group).appendTo("#presenceitemContainer");
					        }
					    }

						//   showPresences(settings);
					}
				    
					showPresences(settings);
				},
				error: function (xhr, ajaxOptions, thrownError) {
					//alert(thrownError);
					setTimeout(function () {
						serviceGetPersonsAndGroups(settings);
					}, 1000);
				}
			});
		}
	}


	// Get presence information from the service
    // Parameters:
    // isInit - fast response from the server - cause all contacts are returned with 'Updating' statuses
	function serviceGetPresences(settings, sips, groups, isInit) {

		var availibility = $.getUrlVar('ava');

		if (availibility == null) {
			availibility = '';
		}

		var serviceUrl = settings.serviceUrl + 'GetPresences?sipUris=' + sips + '&groups=' + groups + '&availability=' + availibility + '&init=' + isInit + '&r=' + Math.random();

		$.ajax({
			type: 'GET',
			url: serviceUrl,
			dataType: 'jsonp',
			success: function (subscriptions) {
			    //NOTE: DO NOT HIDE ALL ITEMS - this causes scroll to the top when page is in the FRAME element in IE:
			    // $('.presenceitem.hidden').hide();
			    
				if (subscriptions == null || subscriptions == 'undefined' || (subscriptions.length == 1
					&& ((subscriptions[0].PresenceSubscription == null || subscriptions[0].PresenceSubscription.SipUri == "{{= sip}}")
						&& (subscriptions[0].GroupSubscription == null || subscriptions[0].GroupSubscription.SipUri == "{{= sip}}")))) {
					setTimeout(function () {
						serviceGetPresences(settings, sips, groups);
					}, 100);
					return;
				}

				var sipList = new Array();
				var grouplist = new Array();

			    for (var i = 0; i < subscriptions.length; i++) {
				    if (subscriptions[i].GroupSubscription != null) {
				        populateGroupPresence(settings, subscriptions[i].GroupSubscription);
				        grouplist.push(subscriptions[i].GroupSubscription.GroupId);
                    } else if (subscriptions[i].PresenceSubscription != null) {
				        populatePresence(settings, subscriptions[i].PresenceSubscription);
				        sipList.push(subscriptions[i].PresenceSubscription.SipUri);
				    }
			    }

			    hideRemovedSipItems(sipList);
			    hideRemovedGroupItems(grouplist);

    		    removeEmptyPresenceBoxes();

			    // order the presence items based on querystring params sortby and sortdirection
				var orderedList = sortPresenceItemsByQuerystring(settings);

			    // give a z-index for all presence items
			    
				for (var i = 0; i < orderedList.length; i++) {
				    $(this).css("z-index", 1000 - i);
				}

				for (var i = 0; i < subscriptions.length; i++) {
				    if (subscriptions[i].GroupSubscription != null) {

				        //get presenceitem containers for this group on the page
				        var groupElements = orderedList.find(".group:contains('" + subscriptions[i].GroupSubscription.GroupId + "')").parents(".presenceitem");

				        groupElements.each(function () {
				            settings.onGroupPresenceItemUpdated.call(this, settings, subscriptions[i].GroupSubscription, $(this));
				        });
				    } else if (subscriptions[i].PresenceSubscription != null) {
                        
				        //get presenceitem containers for this sip on the page
				        var presenceElements = orderedList.find(".sip:contains('" + subscriptions[i].PresenceSubscription.SipUri + "')").parents(".presenceitem");

				        for (var j = 0; j < presenceElements.length; j++) {
				            var tictac = getTicTac(subscriptions[i].PresenceSubscription.Availability);
				            if (tictac != "unknown") {
				                settings.onPresenceItemUpdated.call(presenceElements[j], settings, subscriptions[i].PresenceSubscription, $(presenceElements[j]));
				            }
				        }
				    }
				}
			},
			error: function (xhr, ajaxOptions, thrownError) {
			}
		});
	}

	/// ------------------- ////
	/// End Service Calls  ////
	/// ----------------- ////

	function hideRemovedSipItems(sipList) {
        var sipItems = $("html").find(".sip");
        sipItems.each(function () {
            var item = $(this);
            if ($.inArray($.trim(item[0].innerHTML), sipList) < 0) {
                item.parents(".presenceitem").hide();
            }
        });
	}
    
	function hideRemovedGroupItems(grouplist) {
        var groupItems = $("html").find(".group");
        groupItems.each(function () {
            var item = $(this);
            if ($.inArray($.trim(item[0].innerHTML), grouplist) < 0) {
                item.parents(".presenceitem").hide();
            }
        });    
    }
    

	function populateGroupPresence(settings, groupSubscription) {

		//get presenceitem containers for this group on the page
		var presenceitems = $("html").find(".group:contains('" + groupSubscription.GroupId + "')").parents(".presenceitem");

		presenceitems.each(function () {

			var presenceitem = $(this);

			var toHide = presenceitem.find('.sip').text().trim() == '{{= group}}';

			if (toHide == true || groupSubscription.HidePresence.toString().toLowerCase() == 'true') {
				presenceitem.hide();
				return;
			}

			var tictac = getTicTac(groupSubscription.Availability);

			//add a class describing the availability to .availability elements
			presenceitem.find('.availability').removeClass('availability unknown available offline away dnd busy updating').addClass("availability" + tictac);
			presenceitem.find('.status').removeClass('availability status unknown available offline away dnd busy updating').addClass("status" + tictac);

			// localize the status returned from the service
			localizeStatus(presenceitem, groupSubscription.Status);

			presenceitem.find('.name').html(groupSubscription.GroupName);

			//write the phone into .phone elements,
			//skip skype'd elements because if its skyped, it means it has already been filled in
			presenceitem.find('.phone:not(:has(.skype_pnh_print_container))').html(groupSubscription.Phone);
			// todo: handle skype conflict with: .html("<a href='tel:" + presenceSubscription.Phone + "'>" + presenceSubscription.Phone + "</a>");

			//write the email into .email elements
			presenceitem.find('.email').html(groupSubscription.Email);

			//write the canChat into .canChat elements
			presenceitem.find('.canChat').html(groupSubscription.CanChat.toString());

		    // show presence item
			if (groupSubscription.GroupName != "Unknown") {
			    presenceitem.show();
			}
			else {
			    presenceitem.hide();
			}
		});
	}

	function initChatSession(settings) {

		var serviceUrl = settings.serviceUrl + 'InitGroupChatSession?groupId=' + settings.groupId + '&session=' + settings.session + '&username=' + settings.userName + '&topic=' + settings.topic + "&isInInitialMode=" + settings.isInInitialMode + '&r=' + Math.random();

		$.ajax({
			type: 'GET',
			url: serviceUrl,
			dataType: 'jsonp',
			success: function (chatServiceResponse) {
				if (chatServiceResponse.HasError == "true") {
					var errorCode = chatServiceResponse.ErrorCode;
					var errorMessage = chatServiceResponse.ErrorMessage;
					settings.onError.call(this, errorMessage, errorCode == "SessionError");
				}
			},
			error: function (xhr, ajaxOptions, thrownError) {

				settings.onError.call(this, 'Ajax error :' + ajaxOptions + ' / ' + thrownError, true);
			}
		});
	}

	function removeEmptyPresenceBoxes() {
		var sipItems = $("html").find(".sip:contains('{{= sip}}')").parents(".presenceitem");
		var groupItems = $("html").find(".group:contains('{{= group}}')").parents(".presenceitem");

		sipItems.each(function () {
			var item = $(this);
			item.hide();
		});
		groupItems.each(function () {
			var item = $(this);
			item.hide();
		});
	}

	function populatePresence(settings, presenceSubscription) {

		//get presenceitem containers for this sip on the page
		var presenceitems = $("html").find(".sip:contains('" + presenceSubscription.SipUri + "')").parents(".presenceitem");

		presenceitems.each(function () {

			var presenceitem = $(this);

			var toHide = presenceitem.find('.sip').text().trim() == '{{= group}}';

			if (toHide == true || presenceSubscription.HidePresence.toString().toLowerCase() == 'true') {
				presenceitem.hide();
				return;
			}

			var tictac = getTicTac(presenceSubscription.Availability);

			//add a class describing the availability to .availability elements
		    presenceitem.find('.availability').removeClass('availability unknown available offline away dnd busy updating').addClass("availability" + tictac);
		    presenceitem.find('.status').removeClass('availability status unknown available offline away dnd busy updating').addClass("status" + tictac);

		    if (presenceSubscription.Status == "Updating") {
			    presenceitem.find('.availability').addClass("updating");
			}
		    
			// localize the status returned from the service
			localizeStatus(presenceitem, presenceSubscription.Status);

			//write the email into .email elements
			presenceitem.find('.email').html(presenceSubscription.Email);

			//write the jobtitle into .jobtitle elements
			presenceitem.find('.jobtitle').html(presenceSubscription.JobTitle);

			//write the phone into .phone elements,
			//skip skype'd elements because if its skyped, it means it has already been filled in
			presenceitem.find('.phone:not(:has(.skype_pnh_print_container))').html(presenceSubscription.Phone);
			// todo: handle skype conflict with: .html("<a href='tel:" + presenceSubscription.Phone + "'>" + presenceSubscription.Phone + "</a>");

			//write the mobile into .mobile elements
			//skip skype'd elements because if its skyped, it means it has already been filled in
			presenceitem.find('.mobile:not(:has(.skype_pnh_print_container))').html(presenceSubscription.Mobile);

			//write the ContactName into .name elements
			presenceitem.find('.name').html(presenceSubscription.ContactName);

			//write the canChat into .canChat elements
			presenceitem.find('.canChat').html(presenceSubscription.CanChat.toString());

		    // show presence item
			if (presenceSubscription.ContactName != "Unknown") {
			    presenceitem.show();
			}
			else {
			    presenceitem.hide();
			}
			

		});
	}

	function showPresences(settings) {

		//Get a distinct list of sips on this page
		var sipElements = $("html").find('[class~="sip"]'); //get all sips
		var sips = new Array();
	    
		for (var i = 0; i < sipElements.length; i++) {
		    var sipValue = $.trim($(sipElements[i]).text()); //get the value..
		    if (sipValue != '') {
		        if ($.inArray(sipValue, sips) == -1) { //and when the value is not yet in the array..
		            sips.push(sipValue); //add it   
		        } else {
		            ($(this).parents(".presenceitem")).remove();
		        }
		    }
		}


	    //Get a distinct list of groups on this page
		var groupElements = $("html").find('[class~="group"]'); //get all groups
		var groups = new Array();
		for (var i = 0; i < groupElements.length; i++) {
		    
		    var groupValue = $.trim($(groupElements[i]).text()); //get the value..
		    if (groupValue != '') {
		        if ($.inArray(groupValue, groups) == -1) { //and when the value is not yet in the array..
		            groups.push(groupValue); //add it   
		        } else {
		            ($(this).parents(".presenceitem")).remove();
		        }
		    }

		}


		// call the service to update the presence information
		if (sips.length > 0 || groups.length > 0) {
			if (settings.refreshRate > 0) {
				//execute refreshPresence() every *settings.refreshRate* seconds
			    $("html").everyTime(settings.refreshRate, function () {
			        serviceGetPresences(settings, sips, groups, false);
				});
			}

		    //force immediate execution (otherwise the system will wait *settings.refreshRate* seconds to execute the first time.)
			serviceGetPresences(settings, sips, groups, settings.usePresenceTempInit);
		}


	}

	// return a sorted list of all the presences

	function sortPresences(sortcolumn, sortdirection) {

		var sortColumnField = "." + sortcolumn.toString().toLowerCase();

		var sortedList = $(".presenceitem").sort(function (a, b) {
			var valueA = $(a).find(sortColumnField).html();
			var valueB = $(b).find(sortColumnField).html();
			if (sortdirection != "desc") {
				return valueA.toUpperCase().localeCompare(valueB.toUpperCase());
			} else {
				return valueB.toUpperCase().localeCompare(valueA.toUpperCase());
			}
		});

		return sortedList;
	}

	// position the presence items based on visibility

	function sortPresenceItemsByQuerystring(settings) {

		var items;
		var sortField = $.getUrlVar("sortby");

		if (sortField == null) {
			sortField = settings.sortby;
		}

		var sortDirection = $.getUrlVar("sortdirection");

		if (sortDirection == null) {
			sortDirection = settings.sortdirection;
		}

		if (sortField != null && sortField != '') {

			items = sortPresences(sortField, sortDirection);

			$("#presenceitemContainer").remove(".presenceitem");

			$.each(items, function (index, item) {
				$("#presenceitemContainer").append(item);
			});
		}

		return $(".presenceitem");
	}

	// localize the status string

	function localizeStatus(presenceitem, status) {

		var statusResource = status;

		status = status.toString().toLowerCase();
		if (typeof presenceStatusResource != 'undefined') {
			if (status == "dnd" || status == "do not disturb") {
				statusResource = presenceStatusResource.dnd;
			} else if (status == "away") {
				statusResource = presenceStatusResource.away;
			} else if (status == "busy") {
				statusResource = presenceStatusResource.busy;
			} else if (status == "be right back") {
				statusResource = presenceStatusResource.brb;
			} else if (status == "available" || status == "online") {
				statusResource = presenceStatusResource.available;
			} else if (status == "offline") {
				statusResource = presenceStatusResource.offline;
			} else if (status == "unavailable") {
				statusResource = presenceStatusResource.unavailable;
			} else if (status == "in a meeting") {
				statusResource = presenceStatusResource.inameeting;
			} else if (status == "on the phone") {
				statusResource = presenceStatusResource.onthephone;
			} else if (status == "in a conference call") {
				statusResource = presenceStatusResource.inaconferencecall;
			} else if (status == "updating") {
			    statusResource = presenceStatusResource.updating;
			}
		}

		//write the status into .status elements
		presenceitem.find('.status').html(statusResource);
	}

	// extracts readable presence information based on the status

	function getTicTac(a) {
		var p = " unknown";
        if (a < 3000) {
			p = " unknown";
		} else if (a < 4500) {
			p = " available";
		} else if (a < 6000) {
			p = " away";
		} else if (a < 7500) {
			p = " busy";
		} else if (a < 9000) {
			p = " away";
		} else if (a < 12000) {
			p = " dnd";
		} else if (a < 18000) {
			p = " away";
		} else {
			p = " offline";
		}
		return p;
	}

})(jQuery);

